package org.NooLab.docserver.main;

import java.util.Observable;
import java.util.Observer;

import org.NooLab.docserver.app.DocoProcessControl;
 
import org.NooLab.docserver.app.ProjectSpaceMaintenance;
import org.NooLab.docserver.app.up.IniProperties;
import org.NooLab.docserver.properties.DocumentObserverProperties;
import org.NooLab.docserver.storage.DocoDataBase;
import org.NooLab.structures.ArgumentsPublicIntf;
import org.NooLab.structures.InstanceProcessControlIntf;
import org.NooLab.utilities.files.DFutils;
import org.NooLab.utilities.files.PathFinder;
import org.NooLab.utilities.files.StopFileWatcher;
import org.NooLab.utilities.logging.PrintLog;
import org.NooLab.utilities.strings.StringsUtil;


/**
 * 
 * 
 * 
 * 
 *
 */
@SuppressWarnings("rawtypes")
public class DocumentObserverFactory implements Observer{

	public static final int _GLUE_MODULE_ENV_NONE = 0;

	public static final int _INSTANCE_TYPE_DEFAULT  = 0;
	public static final int _INSTANCE_TYPE_SERVICE  = 1;
	public static final int _INSTANCE_TYPE_EXPLICIT = 2;
	
	// this package must exist  ... and the internal file as well
	String cfgResourceJarPath = "org/NooLab/docserver/resources/default-config-xml" ;

	
	static DocumentObserverFactory  docoSrv;
	DocumentObserverProperties docoProperties ;

	InstanceProcessControlIntf docoProcessControl ;
	
	DocumentObserver documentObserver; 
	DocoDataBase docoDataBase;

	private boolean useStopfile;
	private ArgumentsPublicIntf arguments;

	protected DocumentObserverApplicationEventIntf appInstance=null ;
	
	private int applicationMode;
	
	PrintLog out = new PrintLog(2,false);

	private StopFileWatcher stopper;
	
	// ========================================================================
	protected DocumentObserverFactory(DocumentObserverProperties props){
		docoProperties = props ;
		 
		documentObserver = new DocumentObserver(this) ;
		docoDataBase = new DocoDataBase(docoProperties) ;
		docoProcessControl = new DocoProcessControl(this) ; 
	}
	
	static public DocumentObserverFactory getInstance(DocumentObserverProperties props){
		
		docoSrv = new DocumentObserverFactory(props);
		
		return docoSrv; 
	}
	// ========================================================================

	public int startDocumentObserver(int work_type) {
		
		applicationMode = work_type ;
		
		
		documentObserver.setApplicationMode( applicationMode );
		try {
			
			int z=0;
			
			documentObserver.start();
			
			while ((documentObserver.enginesStarted==false) && (z<1000)){
				PrintLog.Delay(10) ;
			}
			
			
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return documentObserver.startedObservations;
	}

	
	
	public int startDocumentObserver(int work_type, DocumentObserverApplicationEventIntf app) throws Exception {
		int z;
		String mstr="" ;
		
		appInstance = app;
		z = startDocumentObserver(work_type) ;
		
		if (z==1){
			mstr = "process has";
		}else{
			mstr = "processes have";
		}
		documentObserver.out.print(1, z+" observation "+mstr+" been started"); 
			// dummies for search : observation processes have been started ...  observation process has been started
		
		if (useStopfile){
			startStopFileProcess();
		}
		
		return z;
	}

	private void startStopFileProcess() throws Exception {

		
		String path="", homedir="" ;
		
		path = homedir;
		path = (String) arguments.getMappedTopic("homedir") ;
		if (path==null){
			path = ""; // ???
		}
		if (DFutils.folderExists(path)==false){
			
		}
		path = DFutils.createPath(path, "/") ;
		
		String sfile ;
		sfile = (new PathFinder()).getAppBinPath(this.getClass(), true);
		if (sfile.indexOf(".jar")>0){
			sfile = StringsUtil.getLastPartOfString( sfile, "/") ;
		}else{
			sfile = PathFinder.getMainClassName() ; // this does not work: System.getenv("JAVA_MAIN_CLASS");
			if(sfile.length()==0){
				sfile = "NooLabDocumentObserver.jar";
			}
		}
		String ext = StringsUtil.getExtensionFromFilename(sfile);
		sfile = sfile.replace(ext, "")+".stop";
		
		stopper = new StopFileWatcher( (Observer)this, path, sfile, false, 500);
		
		out.print(2, "StopFileWatcher is observing file <"+stopper.getObservedFile()+">");
		
		int z=0; 
		while ((z<500) && (stopper.isObserving()==false)){
			out.delay(2);	z++;
		}
		if (stopper.isObserving()==false){
			out.print(1, "No stop file observer available!");
		}
		
		
		
	}

	// this update is dedicated to the stopfile mechanisms only!
	@Override
	public void update(Observable sendObj, Object msgobj) {
		// TODO Auto-generated method stub
		
	}

	public void close() {
		if (documentObserver!=null){
			documentObserver.stop();
			documentObserver=null;
		}
		
	}

	public static boolean projectSpaceExists(String psLabel) {
		boolean rB= true;
		try {
		
			ProjectSpaceMaintenance psm = new ProjectSpaceMaintenance();
			rB = psm.projectSpaceExists( psLabel ) >= 0;
			
			
		} catch (Exception e) {
			System.err.println(e.getMessage());
		}
		
		return rB;
	}



	public static void completeProjectSpace() throws Exception {
		
		DocumentObserverProperties docoProps ;
		String pslabel ;
		
		 // SomFluidFactory.projectSpaceExists() 
		pslabel = IniProperties.lastProjectName;
		docoProps = docoSrv.getDocoProperties();
		
		if ( docoProps.getApplicationContext().contentEquals( DocumentObserverProperties._APP_CONTEXT_ITEXX)){
			ProjectSpaceMaintenance psm = new ProjectSpaceMaintenance();
			psm.completeProjectSpaceDirectories() ;
		}

	}

	
	public static boolean organizeRawProjectData() {
		String dataSourceFile = "" ;
		boolean rB=false;
		
		ProjectSpaceMaintenance psm = new ProjectSpaceMaintenance();
		psm.organizeRawProjectData();
		
		dataSourceFile = psm.getDataSourceFile();
		
		rB = DFutils.fileExists(dataSourceFile);
		
		if (rB){
			IniProperties.dataSource = dataSourceFile;
		}
		return rB;
	}
	// ========================================================================

	public void saveStartupTrace(int instanceTypeDefault, String startupTraceInfo) {
		
	}

	public int getApplicationMode() {
		return applicationMode;
	}

	public void setApplicationMode(int applicationMode) {
		this.applicationMode = applicationMode;
	}

	public DocumentObserverProperties getDocoProperties() {
		return docoProperties;
	}

	public DocumentObserver getDocumentObserver() {
		return documentObserver;
	}

	public InstanceProcessControlIntf getDocoProcessControl() {
		return docoProcessControl;
	}

	public DocoDataBase getDocoDataBase() {
		return docoDataBase;
	}

	public PrintLog getOut() {
		return out;
	}

	public boolean isUseStopfile() {
		return useStopfile;
	}

	public void setUseStopfile(boolean useStopfile) {
		this.useStopfile = useStopfile;
	}

	public void setArguments(@SuppressWarnings("rawtypes") ArgumentsPublicIntf arguments) {
		if (arguments!=null){
			this.arguments = arguments;
		}
	}
	
	
	
	
	
	
}
